//------------------------------------------
//   frame layer Rate control header file
//				Richard Wang		
//				03/16/2006
//------------------------------------------
#ifndef RTCL_H
#define RTCL_H

#include "math.h"

#define MIN(a,b)  (((a)<(b)) ? (a) : (b))
#define MAX(a,b)  (((a)<(b)) ? (b) : (a))


#define P_SLICE  0
#define B_SLICE  1
#define I_SLICE	 2 	
#define SP_SLICE 3
#define SI_SLICE 4
/*
#define MAX_SAMPLE 5


float	m_bit_rate;
float   m_PreviousBit_Rate;
float	m_rcp_frame_rate;
float	m_frame_rate;
float	m_GAMMAP;
float	m_BETAP;
int		m_Frame_Total_Number_MB;
int		m_TotalQpforPPicture;
int		m_NumberofPPicture;

int		m_NumberofCodedBFrame;
int		m_NumberofCodedPFrame;
int		m_NumberofGOP;

int		m_RC_MAX_QUANT;
int		m_RC_MIN_QUANT;

float	m_BufferSize;
int		m_GOPTargetBufferLevel;
int		m_CurrentBufferFullness;
int		m_TargetBufferLevel;
int		m_MyInitialQp;
int		m_PAverageQp;

// coefficients of the prediction model
float	m_PreviousPictureSATD;
float	m_SATDPictureC1;
float	m_SATDPictureC2;
float	m_PSATDPictureC1;
float	m_PSATDPictureC2;

float	m_PPictureSATD[ MAX_SAMPLE + 1 ];
float	m_PictureSATD[ MAX_SAMPLE + 1 ];
float	m_ReferenceSATD[ MAX_SAMPLE + 1 ];

// quadratic rate-distortion model
float	m_rgQp[ MAX_SAMPLE + 1 ];
float	m_rgRp[ MAX_SAMPLE + 1 ];
float	m_rcp_m_rgQp[ MAX_SAMPLE + 1 ];			// 1.0f / m_rgQp[ i ]
float	m_rcp_m_rgQp_m_rgQp[ MAX_SAMPLE + 1 ];	// 1.0f / ( m_rgQp[ i ] * m_rgQp[ i ] )
float	m_m_rgQp_m_rgRp[ MAX_SAMPLE + 1 ];		// ( m_rgQp[ i ] * m_rgRp[ i ] )
float	m_X1;
float	m_X2;
int		m_Qc;
float	m_Qstep;
int		m_Qp;
int		m_Pm_Qp;
int		m_PreviousQp1;
int		m_PreviousQp2;

float	m_MINVALUE;
float	m_CurrentFrameSATD;		// Richard add for rate control 02-22-2006
float	m_PreviousFrameSATD;	// Richard add for rate control 02-22-2006
int		m_windowSize;
int		m_SATDm_windowSize;
int		DDquant;
int		QPLastPFrame;
int		QPLastGOP;

float	m_Pm_X1;
float	m_Pm_X2;

bool	m_GOPOverdue;

int		m_R;
int		m_Np;
int		m_T, m_T1;

// HRD consideration
int		m_UpperBound1, m_UpperBound2, m_LowerBound;
float	m_InitialDelayOffset;
float	m_OMEGA = 0.9f;

int		m_TotalPFrame;
int		m_DuantQp; 
int		m_PDuantQp;
int		m_DeltaP;

float	RC_a00,   RC_a01,   RC_a10,   RC_a11,   RC_b0,   RC_b1;
float	SATD_a00, SATD_a01, SATD_a10, SATD_a11, SATD_b0, SATD_b1;
*/
typedef struct
{
	float	        frame_rate;
	float	        bit_rate;
	int		        jumpd;
	int		        width;
	int		        height;
	int		        initialQP;
	int             u32IPInterval;
	int             img_type;
	unsigned int    interval_count;
}SEQUENCE;

#define H264_RateControl SEQUENCE

// function.
void rc_init_seq( SEQUENCE* );
void rc_init_GOP( int, SEQUENCE* );
void rc_update_pict_frame( int );
void rc_init_pict( int, float );
void rc_update_pict(int );

int   updateQuantizationParameter( int );
void  updateRCModel ( float, int, int );
void  updateSATDModel( int );
void  RCModelEstimator (int, int );
void  SATDModelEstimator (int, int );
int   Qstep2QP( float );
float QP2Qstep( int );
void H264RateControlInit(SEQUENCE *_seq,float br,float frame_rate,int width,int height,int u32IPInterval,int qmax,int qmin);
int H264RateControlGetQuant(SEQUENCE *_seq);
void H264RateControlUpdate(SEQUENCE *_seq,int bitstream_size,unsigned int frame_cost);
#endif
